package com.incrediblesoft.redjey.demo;

import com.incrediblesoft.redjey.UIManager;

import javax.microedition.lcdui.*;

public class RedJDemoCanvas extends Canvas implements Runnable
{
    /**
     * Instance
     */
    private static RedJDemoCanvas instance;

    /**
     * Animation thread
     */
    private volatile Thread animationThread = null;

    /**
     * Perfomance settings
     */
    private int FPS;
    private int MILLIS_PER_TICK;
    /**
     * Cached screen dimensions
     */
    private int canvasWidth;
    private int canvasHeight;
    

    /**
     * State
     */
    public static final int IDLE_STATE = 0;
    public static final int INIT_STATE = 1;
    public static final int INIT_AND_WORK_STATE = 2;
    public static final int PAUSED_STATE = 3;
    public static final int WORKING_STATE = 4;
    public static final int EXIT_STATE = 5;

    public static int _FPS = 0;
    /**
     * State
     */
    private int state;

    private boolean isPaintEnds;


    public RedJDemoCanvas()
    {
        super();
        instance = this;
    }

    public static RedJDemoCanvas getInstance()
    {
        return instance;
    }

    public int getWidth()
    {
        return canvasWidth;
    }

    public int getHeight()
    {
        return canvasHeight;
    }

    public void setState(int state)
    {
        this.state = state;

        switch(state)
        {
            case INIT_STATE:
            case INIT_AND_WORK_STATE:
                setFullScreenMode(true);
                repaint();
                serviceRepaints();
                break;
            
            case WORKING_STATE:
                animationThread = new Thread(this);
                animationThread.start();
                break;

            case EXIT_STATE:
                animationThread = null;
                break;
        }
    }

    public int getState()
    {
        return state;
    }

    public void setFps(int fps)
    {
        if (fps > 0)
        {
            FPS = fps;
            MILLIS_PER_TICK = 1000 / FPS;
        }
    }

    /**
     * Thread
     */
    public void run()
    {
        Thread currentThread = Thread.currentThread();
        long timePrevious = 0;

        // This ends when animationThread is set to null, or when
        // it is subsequently set to a new thread; either way, the
        // current thread should terminate
        while (currentThread == animationThread)
        {
            if (isShown())
            {
                long dt = System.currentTimeMillis() - timePrevious;
                if (dt < MILLIS_PER_TICK)
                {
                    try
                    {
                        Thread.sleep(MILLIS_PER_TICK - dt);
                    }
                    catch (InterruptedException ex)
                    {
                        // ignored
                    }

                    dt = System.currentTimeMillis() - timePrevious;
                }

                //System.out.println("fps="+(1000 / dt));
                _FPS = (int) (1000 / dt);

                timePrevious = System.currentTimeMillis();

                switch(state)
                {
                    case WORKING_STATE:
                        doWorkingState((int) dt);
                        break;
                }
            }



        }
    }

    private synchronized void doWorkingState(int dt)
    {
        try
        {
            if (FPS > 0)
                UIManager.tick(dt);

            isPaintEnds = false;

            repaint(0, 0, getWidth(), getHeight());

            while (!isPaintEnds)
            {
                wait();
            }
        }
        catch (NullPointerException ex)
        {
            ex.printStackTrace();
        }
        catch (InterruptedException ex)
        {
            ex.printStackTrace();
        }
    }

    protected synchronized void keyPressed(int keycode)
    {
        UIManager.keyPressed(keycode);
    }

    protected synchronized void keyReleased(int keycode)
    {
        UIManager.keyReleased(keycode);
    }

    protected void pointerPressed(int x, int y)
    {
        UIManager.pointerPressed(x, y);
    }

    protected void pointerReleased(int x, int y)
    {
        UIManager.pointerReleased(x, y);
    }

    protected void pointerDragged(int x, int y)
    {
        UIManager.pointerDragged(x, y);
    }

    /**
     * Guess what is it
     */
    protected synchronized void paint(Graphics g)
    {
        switch(state)
        {
            case INIT_STATE:
            case INIT_AND_WORK_STATE:
                System.out.println("Painting INIT STATE");
                g.setColor(0xFFFFFFFF);
                g.fillRect(0, 0, 500, 500);
                //set once
                if (canvasWidth == 0) canvasWidth = super.getWidth();
                if (canvasHeight == 0) canvasHeight = super.getHeight();
                //canvasWidth = 176;
                //canvasHeight = 208;
                if (state == INIT_AND_WORK_STATE)
                    setState(WORKING_STATE);
                else
                    setState(IDLE_STATE);
                break;

            case WORKING_STATE:
                UIManager.paint(g);
                break;
        }

        isPaintEnds = true;
        notifyAll();
    }

    protected void hideNotify()
    {
        UIManager.hideNotify();
    }
    protected void showNotify()
    {        
        setFullScreenMode(true);
        UIManager.showNotify();
    }
}
